﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;

namespace Xeno.Core
{
    public enum TextureFormat
    {
        Alpha,Rgb,Rgba
    }
    public class XenoTexture
    {
        public int Texture = 0;
        public int Width { get; set; }
        public int Height { get; set; }
        public TextureFormat Format { get; set; }
        public virtual void Bind(int texunit)
        {

        }
        public virtual void Unbind(int texunit)
        {

        }
    }
    public class XenoTextureDepth : XenoTexture
    {
         public XenoTextureDepth(int width,int height)
        {
             Bitmap TextureBitmap = new Bitmap(width,height);
            //get the data out of the bitmap
            System.Drawing.Imaging.BitmapData TextureData =
            TextureBitmap.LockBits(
                    new System.Drawing.Rectangle(0, 0, TextureBitmap.Width, TextureBitmap.Height),
                    System.Drawing.Imaging.ImageLockMode.ReadOnly,
                    System.Drawing.Imaging.PixelFormat.Format24bppRgb
                );

            //Code to get the data to the OpenGL Driver

            GL.Enable(EnableCap.Texture2D);
            //generate one texture and put its ID number into the "Texture" variable
            GL.GenTextures(1, out Texture);
            //tell OpenGL that this is a 2D texture
            GL.BindTexture(TextureTarget.Texture2D, Texture);

            //the following code sets certian parameters for the texture
            GL.TexEnv(TextureEnvTarget.TextureEnv,
            TextureEnvParameter.TextureEnvMode,
            (float)TextureEnvMode.Replace);
            GL.TexParameter(TextureTarget.Texture2D,
            TextureParameterName.TextureMinFilter,
            (float)TextureMinFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D,
            TextureParameterName.TextureMagFilter,
            (float)TextureMagFilter.Linear);

            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.DepthComponent, TextureBitmap.Width, TextureBitmap.Height, 0, PixelFormat.DepthComponent, PixelType.UnsignedByte, TextureData.Scan0);

            Width = TextureBitmap.Width;
            Height = TextureBitmap.Height;
            Format = TextureFormat.Rgb;

            //load the data by telling OpenGL to build mipmaps out of the bitmap data
            //.Build2DMipmap(TextureTarget.Texture2D,
            //   (int)PixelInternalFormat.Three, TextureBitmap.Width, TextureBitmap.Height,
            // PixelFormat.Bgr, PixelType.UnsignedByte,
            // TextureData.Scan0
            // );

            //free the bitmap data (we dont need it anymore because it has been passed to the OpenGL driver
            TextureBitmap.UnlockBits(TextureData);
            GL.BindTexture(TextureTarget.Texture2D, 0);
            GL.Disable(EnableCap.Texture2D);
        }
    }
    public class XenoTexture2D : XenoTexture
    {
        public XenoTexture2D(int width,int height)
        {
             Bitmap TextureBitmap = new Bitmap(width,height);
            //get the data out of the bitmap
            System.Drawing.Imaging.BitmapData TextureData =
            TextureBitmap.LockBits(
                    new System.Drawing.Rectangle(0, 0, TextureBitmap.Width, TextureBitmap.Height),
                    System.Drawing.Imaging.ImageLockMode.ReadOnly,
                    System.Drawing.Imaging.PixelFormat.Format24bppRgb
                );

            //Code to get the data to the OpenGL Driver

            GL.Enable(EnableCap.Texture2D);
            //generate one texture and put its ID number into the "Texture" variable
            GL.GenTextures(1, out Texture);
            //tell OpenGL that this is a 2D texture
            GL.BindTexture(TextureTarget.Texture2D, Texture);

            //the following code sets certian parameters for the texture
            GL.TexEnv(TextureEnvTarget.TextureEnv,
            TextureEnvParameter.TextureEnvMode,
            (float)TextureEnvMode.Replace);
            GL.TexParameter(TextureTarget.Texture2D,
            TextureParameterName.TextureMinFilter,
            (float)TextureMinFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D,
            TextureParameterName.TextureMagFilter,
            (float)TextureMagFilter.Linear);

            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, TextureBitmap.Width, TextureBitmap.Height, 0, PixelFormat.Rgb, PixelType.UnsignedByte, TextureData.Scan0);

            Width = TextureBitmap.Width;
            Height = TextureBitmap.Height;
            Format = TextureFormat.Rgb;

            //load the data by telling OpenGL to build mipmaps out of the bitmap data
            //.Build2DMipmap(TextureTarget.Texture2D,
            //   (int)PixelInternalFormat.Three, TextureBitmap.Width, TextureBitmap.Height,
            // PixelFormat.Bgr, PixelType.UnsignedByte,
            // TextureData.Scan0
            // );

            //free the bitmap data (we dont need it anymore because it has been passed to the OpenGL driver
            TextureBitmap.UnlockBits(TextureData);
            GL.BindTexture(TextureTarget.Texture2D, 0);
            GL.Disable(EnableCap.Texture2D);
        }
        public XenoTexture2D(Bitmap bitmap)
        {
            Bitmap TextureBitmap = bitmap;
            //get the data out of the bitmap
            System.Drawing.Imaging.BitmapData TextureData =
            TextureBitmap.LockBits(
                    new System.Drawing.Rectangle(0, 0, TextureBitmap.Width, TextureBitmap.Height),
                    System.Drawing.Imaging.ImageLockMode.ReadOnly,
                    System.Drawing.Imaging.PixelFormat.Format24bppRgb
                );

            //Code to get the data to the OpenGL Driver

            GL.Enable(EnableCap.Texture2D);
            //generate one texture and put its ID number into the "Texture" variable
            GL.GenTextures(1, out Texture);
            //tell OpenGL that this is a 2D texture
            GL.BindTexture(TextureTarget.Texture2D, Texture);

            //the following code sets certian parameters for the texture
            GL.TexEnv(TextureEnvTarget.TextureEnv,
            TextureEnvParameter.TextureEnvMode,
            (float)TextureEnvMode.Replace);
            GL.TexParameter(TextureTarget.Texture2D,
            TextureParameterName.TextureMinFilter,
            (float)TextureMinFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D,
            TextureParameterName.TextureMagFilter,
            (float)TextureMagFilter.Linear);

            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, TextureBitmap.Width, TextureBitmap.Height, 0, PixelFormat.Rgb, PixelType.UnsignedByte, TextureData.Scan0);

            Width = TextureBitmap.Width;
            Height = TextureBitmap.Height;
            Format = TextureFormat.Rgb;

            //load the data by telling OpenGL to build mipmaps out of the bitmap data
            //.Build2DMipmap(TextureTarget.Texture2D,
            //   (int)PixelInternalFormat.Three, TextureBitmap.Width, TextureBitmap.Height,
            // PixelFormat.Bgr, PixelType.UnsignedByte,
            // TextureData.Scan0
            // );

            //free the bitmap data (we dont need it anymore because it has been passed to the OpenGL driver
            TextureBitmap.UnlockBits(TextureData);
            GL.BindTexture(TextureTarget.Texture2D, 0);
            GL.Disable(EnableCap.Texture2D);
        }
        public XenoTexture2D(string path)
        {
            if (System.IO.File.Exists(path))
            {
                //make a bitmap out of the file on the disk
                Bitmap TextureBitmap = new Bitmap(path);
                //get the data out of the bitmap
                System.Drawing.Imaging.BitmapData TextureData =
                TextureBitmap.LockBits(
                        new System.Drawing.Rectangle(0, 0, TextureBitmap.Width, TextureBitmap.Height),
                        System.Drawing.Imaging.ImageLockMode.ReadOnly,
                        System.Drawing.Imaging.PixelFormat.Format24bppRgb
                    );

                //Code to get the data to the OpenGL Driver

                GL.Enable(EnableCap.Texture2D);
                //generate one texture and put its ID number into the "Texture" variable
                GL.GenTextures(1, out Texture);
                //tell OpenGL that this is a 2D texture
                GL.BindTexture(TextureTarget.Texture2D, Texture);

                //the following code sets certian parameters for the texture
                GL.TexEnv(TextureEnvTarget.TextureEnv,
                TextureEnvParameter.TextureEnvMode,
                (float)TextureEnvMode.Modulate);
                GL.TexParameter(TextureTarget.Texture2D,
                TextureParameterName.TextureMinFilter,
                (float)TextureMinFilter.Linear);
                GL.TexParameter(TextureTarget.Texture2D,
                TextureParameterName.TextureMagFilter,
                (float)TextureMagFilter.Linear);
                
                GL.TexImage2D(TextureTarget.Texture2D,0,PixelInternalFormat.Rgba,TextureBitmap.Width,TextureBitmap.Height,0,PixelFormat.Rgb,PixelType.UnsignedByte,TextureData.Scan0);
                
                Width = TextureBitmap.Width;
                Height = TextureBitmap.Height;
                Format = TextureFormat.Rgb;

                //load the data by telling OpenGL to build mipmaps out of the bitmap data
                //.Build2DMipmap(TextureTarget.Texture2D,
                 //   (int)PixelInternalFormat.Three, TextureBitmap.Width, TextureBitmap.Height,
               // PixelFormat.Bgr, PixelType.UnsignedByte,
               // TextureData.Scan0
               // );

                //free the bitmap data (we dont need it anymore because it has been passed to the OpenGL driver
                TextureBitmap.UnlockBits(TextureData);
                GL.BindTexture(TextureTarget.Texture2D, 0);
                GL.Disable(EnableCap.Texture2D);
            }
        }

        public override void Bind(int TexUnit)
        {
         //   GL.ClientActiveTexture((TextureUnit)((int)TextureUnit.Texture0+TexUnit));
        //    GL.ActiveTexture((TextureUnit)((int)TextureUnit.Texture0+TexUnit));
            GL.Enable(EnableCap.Texture2D);
            GL.BindTexture(TextureTarget.Texture2D, Texture);
        }
        public override void Unbind(int TexUnit)
        {
            //GL.ClientActiveTexture((TextureUnit)((int)TextureUnit.Texture0 + TexUnit));
           // GL.ActiveTexture((TextureUnit)((int)TextureUnit.Texture0 + TexUnit));
            GL.BindTexture(TextureTarget.Texture2D, 0);
            GL.Disable(EnableCap.Texture2D);
        }
    }
}
